// Copyright 2011 Google Inc. All Rights Reserved.

/**
 * @fileoverview This module provides a way to measure network latency via HTTP.
 *
 * @author gavaletz@google.com (Eric Gavaletz)
 *
 * This test operates by downloading tiny images (should fit into one packet
 * over the same connection many times.
 *
 * small images
 *
 * http://i2.ytimg.com/vi/EUaphGX9AyI/1.jpg
 * http://i2.ytimg.com/i/augF6Vv2TDgBRvKVeSqyUg/1.jpg
 * http://i2.ytimg.com/i/9Qx2y24krfqiOsZuAg3JCQ/1.jpg
 * http://i3.ytimg.com/i/zYb3rxepPWrB61MCKQGrPw/1.jpg
 * https://ads.youtube.com/img/icon_pdf_16x16.gif
 */


goog.provide('late');


goog.require('datastore');
goog.require('goog.array');
goog.require('page');
goog.require('resptime');


/**
 * The name for this test to be used when displaying results.
 *
 * @type {string}
 * @const
 */
late.testName = 'latency';


/**
 * The server part of the url for latency test image files.
 *
 * @type {string}
 */
late.server = 'i1.ytimg.com';


/**
 * Sets the server name/ip.  Usually just used from the server.
 *
 * @param {string} s the path to be used.
 */
late.setServer = function(s) {
  late.server = s;
};
//used by the closure compiler to eport this function call
goog.exportProperty(window, 'lateSetServer', late.setServer);


/**
 * The resource part of the url for latency test image files.
 *
 * @type {string}
 */
late.resource = '/i/augF6Vv2TDgBRvKVeSqyUg/1.jpg';


/**
 * Sets the resource (image) path.  Usually just used from the server.
 *
 * @param {string} s the path to be used.
 */
late.setResource = function(s) {
  late.resource = s;
};
//used by the closure compiler to eport this function call
goog.exportProperty(window, 'lateSetResource', late.setResource);


/**
 * The limit (upper) for the number of files to be loaded.
 *
 * @type {number}
 */
late.maxPings = 100;


/**
 * Sets the maximum number of pings.  Usually just used from the server.
 *
 * @param {number} n the maximum number of files to load.
 */
late.setMaxPings = function(n) {
  late.maxPings = n;
};
//used by the closure compiler to eport this function call
goog.exportProperty(window, 'lateSetMaxPings', late.setMaxPings);


/**
 * The maximum amount of time that this test should be allowed to run.
 *
 * @type {number}
 */
late.timeLimit = 1000.0;


/**
 * Sets the time limit.  Usually just used from the server.
 *
 * @param {number} n the maximum time in seconds.
 */
late.setTimeLimit = function(n) {
  late.timeLimit = n;
};
//used by the closure compiler to eport this function call
goog.exportProperty(window, 'lateSetTimeLimit', late.setTimeLimit);


/**
 * The limit (lower) for the number of files to be loaded.
 *
 * @type {number}
 */
late.minPings = 10;


/**
 * Sets the minimum number of pings.  Usually just used from the server.
 *
 * @param {number} n the minimum number of files to load.
 */
late.setMinPings = function(n) {
  late.minPings = n;
};
//used by the closure compiler to eport this function call
goog.exportProperty(window, 'lateSetMinPings', late.setMinPings);


/**
 * The minimum response time approximating a RTT.
 *
 * @type {number}
 */
late.minRtt;


/**
 * The median response time approximating a RTT.
 *
 * @type {number}
 */
late.medRtt;


/**
 * The next thing to do.
 *
 * @type {function()}
 */
late.nextFunction;


/**
 * Sets up the netscore state to receive updates and loads the first image.
 */
late.start = function() {
  datastore.json['lateServer'] = late.server;
  datastore.json['lateResource'] = late.resource;
  datastore.json['lateObjSize'] = late.objSize;
  page.progressSetTestName(late.testName);
  page.progressSetTestMessage(nsi18n('lateProgress'));
  resptime.setup(late.server, late.resource, late.maxPings, late.minPings,
      late.timeLimit, late.finish, page.progressSetProgressBar);
  resptime.start();
};


/**
 * Calculates an average latency metric and updates the page with that result.
 *
 * @param {Array.<number>} data the list of response times.
 */
late.finish = function(data) {
  datastore.json['lateDelay'] = goog.array.clone(data);
  goog.array.sort(data);
  late.minRtt = data[0];
  late.medRtt = data[Math.round(data.length / 2)];
  datastore.json['lateMinRtt'] = late.minRtt;
  datastore.json['lateMedRtt'] = late.medRtt;
  page.progressClear();
  if (late.nextFunction) {
    late.nextFunction();
  }
};


/**
 * Displays results based on the data stored in the datastore.
 */
late.results = function() {
  var lateDisplayDiv = goog.dom.createDom('div', {'class': 'displayChart'});
  var lateDescrip1Div = goog.dom.createDom('div', {'class': 'message'},
      nsi18n('lateDescrip1'));
  var otherDescripDiv = goog.dom.createDom('div', {'class': 'message'},
      nsi18n('lateDescrip2'));
  var otherTableDisplayDiv = goog.dom.createDom('div', {'class': 'table'});
  var contentDiv = goog.dom.createDom('div', {}, lateDescrip1Div,
      lateDisplayDiv, otherDescripDiv, otherTableDisplayDiv);
  page.resultsAppend(late.testName, contentDiv);

  // results will generate the counts for us.
  var dataObj = results.dataToObj(null, datastore.json['lateDelay'],
      nsi18n('Ping Count'), nsi18n('RTT (ms)'), 'number', 'number');
  results.scatterChart(dataObj, 'RTT', lateDisplayDiv);

  var otherLables = ['Server', 'Resource', nsi18n('Median RTT (ms)'),
        nsi18n('Minimum RTT (ms)')];
  var otherValues = [datastore.json['lateServer'],
    datastore.json['lateResource'], datastore.json['lateMedRtt'],
    datastore.json['lateMinRtt']];
  var otherDataObj = results.dataToObj(otherLables, otherValues,
      nsi18n('Field'), nsi18n('Value'), 'string', 'number');
  results.table(otherDataObj, otherTableDisplayDiv);
};
